package com.ytjj.qmyx.users.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.util.StringUtil;
import com.tencent.ads.model.ActionType;
import com.tencent.ads.model.UserActionsAddResponse;
import com.ytjj.common.api.CommonResult;
import com.ytjj.common.api.ResultCode;
import com.ytjj.common.constants.*;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.service.RedisService;
import com.ytjj.common.utils.CopyWriterConfigUtil;
import com.ytjj.common.utils.OrderUtils;
import com.ytjj.common.utils.SysConfigUtil;
import com.ytjj.common.utils.TokenUtil;
import com.ytjj.qmyx.mall.client.MallClient;
import com.ytjj.qmyx.mall.model.DynamicDto;
import com.ytjj.qmyx.mall.model.UserRegisterRequestDto;
import com.ytjj.qmyx.users.constants.SmsConstant;
import com.ytjj.qmyx.users.constants.UserLoginConstant;
import com.ytjj.qmyx.users.dao.UsersAppLoginDao;
import com.ytjj.qmyx.users.dao.UsersDao;
import com.ytjj.qmyx.users.enums.DynamicStatusEnums;
import com.ytjj.qmyx.users.enums.UsersStatusEnums;
import com.ytjj.qmyx.users.mapper.LoginLogMapper;
import com.ytjj.qmyx.users.mapper.UsersBalanceRecordMapper;
import com.ytjj.qmyx.users.mapper.UsersInfoMapper;
import com.ytjj.qmyx.users.mapper.UsersMapper;
import com.ytjj.qmyx.users.model.*;
import com.ytjj.qmyx.users.model.dto.AdvertCallbackDto;
import com.ytjj.qmyx.users.model.request.AppLoginRequest;
import com.ytjj.qmyx.users.model.request.LoginRequest;
import com.ytjj.qmyx.users.model.request.RegisterRequest;
import com.ytjj.qmyx.users.model.response.UsersResponse;
import com.ytjj.qmyx.users.service.LoginService;
import com.ytjj.qmyx.users.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description 登录业务
 * 
 * @Version 1.0
 * 
 */

@Service
@Slf4j
@RefreshScope
public class LoginServiceImpl implements LoginService {


    private final RedisService redisService;

    @Resource
    private UsersMapper usersMapper;
    @Resource
    private UsersDao usersDao;
    @Resource
    private UsersInfoMapper usersInfoMapper;
    @Resource
    private LoginLogMapper loginLogMapper;
    @Resource
    private MallClient mallClient;
    @Resource
    private SysConfigUtil sysConfigUtil;
    @Resource
    private UsersBalanceRecordMapper usersBalanceRecordMapper;
    @Resource
    private CopyWriterConfigUtil copyWriterConfigUtil;
    /**
     * 登录黑名单
     */
    @Value("${blacklist.tel:18811193193,15754211002,13052614691,18873058010}")
    private String blackListTel;

    public LoginServiceImpl(RedisService redisService) {
        this.redisService = redisService;
    }


    /**
     * 手机号+验证码登录
     *
     * @param registerRequest
     * @return
     */
    @Override
    @Transactional
    public CommonResult register(RegisterRequest registerRequest) {
        // iOS测试用户
        if ("17388888888".equals(registerRequest.getTelephone())) {
            // 处理用户信息
            UsersResponse usersResponse = dealWithUser(registerRequest);
            return CommonResult.success(usersResponse);
        }
        //首先比对验证码是否失效
        String redisAuthCode = redisService.get(SmsConstant.REDIS_KEY_PREFIX_AUTH_CODE_PHONEREGISTER + registerRequest.getTelephone());
        if (StringUtils.isEmpty(redisAuthCode)) {
            //如果未取到则过期
            return CommonResult.failed(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.VERIFICATION_CODE_ERROR));
        }
        if (!"".equals(redisAuthCode) && !registerRequest.getAuthCode().equals(redisAuthCode)) {
            return CommonResult.failed(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.VERIFICATION_CODE_ERROR));
        }
        // 处理用户信息
        UsersResponse usersResponse = dealWithUser(registerRequest);
        updateAppLogin(usersResponse.getId(), usersResponse.getToken());
        try {
            usersResponse.setTalentFlag(checkUserIsTalent(usersResponse.getId(), DynamicStatusEnums.PASS.getCode()));
            if (null == usersResponse.getIsQuality() || 0 == usersResponse.getIsQuality()) {
                if (1 == usersResponse.getTalentFlag()) {
                    usersResponse.setIsQuality(1);
                }else {
                    usersResponse.setIsQuality(checkUserIsTalent(usersResponse.getId(), null));
                }
            }
        } catch (Exception e) {
            log.error("===获取用户达人标志位异常==={}", usersResponse.getId());
            log.error("{}", e);
        }
        try {
            usersResponse.setPayFlag(0);
            DynamicDto dto = mallClient.queryCountByTelRpc(usersResponse.getTel());
            Integer payNum = dto.getNum();
            if (null != payNum && payNum > 0) {
                usersResponse.setPayFlag(1);
            }
        } catch (Exception e) {
            log.error("===获取用户支付订单总数异常==={}", e);
        }
        return CommonResult.success(usersResponse);
    }

    /**
     * 判断用户是否是达人
     * 判断标准：用户是否存在审核通过的测评
     * @return 1-是达人 0-非达人
     */
    @Override
    public Integer checkUserIsTalent(Integer userId, Integer status) {
        DynamicDto dto = mallClient.getDynamicCountByUserId(userId, status);
        Integer count = dto.getNum();
        if (null == count || count <= 0) {
            return 0;
        }
        return 1;
    }

    /**
     * 手机号+验证码登录
     *
     * @param registerRequest
     * @return
     */
    @Override
    public CommonResult tokenLogin(RegisterRequest registerRequest) {
        UsersResponse usersResponse = dealWithUser(registerRequest);
        usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
        updateAppLogin(usersResponse.getId(), usersResponse.getToken());
        return CommonResult.success(usersResponse);
    }

    @Override
    public CommonResult wxTokenLogin(RegisterRequest registerRequest) {
        UsersResponse usersResponse = null;
        LoginLog loginLog = new LoginLog();
        // 判断手机号是否存在
        Users phoneUser = usersDao.queryUsersByTel(registerRequest.getTelephone());
        if (null != phoneUser) {
            if (phoneUser.getStatus().byteValue() == UsersStatusEnums.unregister.getStatus()) {
                phoneUser.setStatus(UsersStatusEnums.active.getStatus());
            }
            // 如果手机号已存在 登录成功，更新openid ，如果uid 为null ，更新uid 否不更新uid
            Users uidUsers = usersDao.queryUsersByUid(registerRequest.getUnionid());
            if (null == uidUsers) {
                phoneUser.setToken(GetTokenUtil.getToken());
                phoneUser.setWxUnionid(registerRequest.getUnionid());
                phoneUser.setWxOpenid(registerRequest.getOpenid());
                usersMapper.updateByPrimaryKeySelective(phoneUser);
            } else {
                phoneUser.setToken(GetTokenUtil.getToken());
                phoneUser.setWxOpenid(registerRequest.getOpenid());
                usersMapper.updateByPrimaryKeySelective(phoneUser);
            }
            UsersInfo existUsersInfo = usersInfoMapper.selectByPrimaryKey(phoneUser.getId());
            usersResponse = new UsersResponse(phoneUser, existUsersInfo);
            if (StringUtils.isEmpty(usersResponse.getHeadImg())) {
                usersResponse.setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
            }
            usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
            // 登录日志记录
            loginLog.setUserId(usersResponse.getId())
                    .setLoginTime(new Date())
                    .setPlatform(registerRequest.getPlatform())
                    .setIp(registerRequest.getIp())
                    .setVersion(registerRequest.getVersion())
                    .setPhoneModel(registerRequest.getPhoneModel());
            loginLogMapper.insertSelective(loginLog);

            // 用户我的钱包明细判断有无登录赠送记录
            UsersBalanceRecordExample example = new UsersBalanceRecordExample();
            example.createCriteria()
                    .andUserIdEqualTo(phoneUser.getId())
                    .andSourceEqualTo("LOGIN_GIVE");
            List<UsersBalanceRecord> usersBalanceRecords = usersBalanceRecordMapper.selectByExample(example);
            // 该用户是否支付过
            usersResponse.setIsPayOrder(this.isPayBytel(usersResponse.getTel()));
            redisService.set(phoneUser.getToken(), JSONObject.toJSONString(usersResponse));
            redisService.expire(phoneUser.getToken(), TokenConstants.EXPIRE_SECONDS);
        } else {
            // 如果手机号不存在  查询uid 是否存在 如果uid 存在 不保存uid
            // 保存openid 和手机号 如果uid 不存在 保存openid 和uid和手机号
            Users uidUsers = usersDao.queryUsersByUid(registerRequest.getUnionid());
            if (null == uidUsers) {
                Users newUser = new Users()
                        .setTel(registerRequest.getTelephone())
                        .setStatus(UsersStatusEnums.active.getStatus())
                        .setWxOpenid(registerRequest.getOpenid())
                        .setWxUnionid(registerRequest.getUnionid())
                        // 随机账号生成和订单公共
                        .setAccount(OrderUtils.getRandomAccount())
                        .setToken(GetTokenUtil.getToken())
                        .setNickname(registerRequest.getTelephone())
                        .setSource(registerRequest.getSource());
                // 数据库插入用户基础信息
                usersMapper.insertSelective(newUser);
                UsersInfo usersInfo = new UsersInfo()
                        .setId(newUser.getId())
                        .setChannel(registerRequest.getChannel())
                        .setEmail("")
                        .setRegisterIp(registerRequest.getIp())
                        .setRegisterTime(new Date())
                        .setScore(Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE_APP)))
                        .setTemporarySore(Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE_APP)))
                        .setTemporarySoreTime(Date.from(LocalDateTime.now().plusDays(7).atZone(ZoneId.systemDefault()).toInstant()))
                        .setMoney(new BigDecimal(sysConfigUtil.getSysConfig(SysConfigConstants.LOGIN_MONEY)))
                        .setTotalMoney(new BigDecimal(sysConfigUtil.getSysConfig(SysConfigConstants.LOGIN_MONEY)))
                        .setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
                // 数据库插入用户附属表信息
                usersInfoMapper.insertSelective(usersInfo);
                usersResponse = new UsersResponse(newUser, usersInfo);
                if (StringUtils.isEmpty(usersResponse.getHeadImg())) {
                    usersResponse.setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
                }
                usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
                // 登录日志记录
                loginLog.setUserId(usersResponse.getId())
                        .setLoginTime(new Date())
                        .setPlatform(registerRequest.getPlatform())
                        .setIp(registerRequest.getIp())
                        .setVersion(registerRequest.getVersion())
                        .setPhoneModel(registerRequest.getPhoneModel());
                loginLogMapper.insertSelective(loginLog);

                // 该用户是否支付过
                usersResponse.setIsPayOrder(this.isPayBytel(usersResponse.getTel()));
                redisService.set(newUser.getToken(), JSONObject.toJSONString(usersResponse));
                redisService.expire(newUser.getToken(), TokenConstants.EXPIRE_SECONDS);
            } else {
                Users newUser = new Users()
                        .setTel(registerRequest.getTelephone())
                        .setStatus(UsersStatusEnums.active.getStatus())
                        .setWxOpenid(registerRequest.getOpenid())
                        // 随机账号生成和订单公共
                        .setAccount(OrderUtils.getRandomAccount())
                        .setToken(GetTokenUtil.getToken())
                        .setNickname(registerRequest.getTelephone())
                        .setSource(registerRequest.getSource());
                // 数据库插入用户基础信息
                usersMapper.insertSelective(newUser);
                UsersInfo usersInfo = new UsersInfo()
                        .setId(newUser.getId())
                        .setChannel(registerRequest.getChannel())
                        .setEmail("")
                        .setScore(Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE_APP)))
                        .setTemporarySore(Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE_APP)))
                        .setTemporarySoreTime(Date.from(LocalDateTime.now().plusDays(7).atZone(ZoneId.systemDefault()).toInstant()))
                        .setRegisterIp(registerRequest.getIp())
                        .setRegisterTime(new Date())
                        .setMoney(new BigDecimal(sysConfigUtil.getSysConfig(SysConfigConstants.LOGIN_MONEY)))
                        .setTotalMoney(new BigDecimal(sysConfigUtil.getSysConfig(SysConfigConstants.LOGIN_MONEY)))
                        .setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
                // 数据库插入用户附属表信息
                usersInfoMapper.insertSelective(usersInfo);
                usersResponse = new UsersResponse(newUser, usersInfo);
                usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
                // 登录日志记录
                loginLog.setUserId(usersResponse.getId())
                        .setLoginTime(new Date())
                        .setPlatform(registerRequest.getPlatform())
                        .setIp(registerRequest.getIp())
                        .setVersion(registerRequest.getVersion())
                        .setPhoneModel(registerRequest.getPhoneModel());
                loginLogMapper.insertSelective(loginLog);

                // 该用户是否支付过
                usersResponse.setIsPayOrder(this.isPayBytel(usersResponse.getTel()));
                redisService.set(newUser.getToken(), JSONObject.toJSONString(usersResponse));
                redisService.expire(newUser.getToken(), TokenConstants.EXPIRE_SECONDS);
            }
        }
        return CommonResult.success(usersResponse);
    }

    @Override
    public void makeTag(RegisterRequest registerRequest) {
        List<String> labels = registerRequest.getLabels();
        String labelText = null;
        if (!CollectionUtils.isEmpty(labels)) {
            labelText = labels.stream().collect(Collectors.joining(","));
        }
        Users users = usersMapper.selectByPrimaryKey(registerRequest.getUserId());
        UsersInfo usersInfo = new UsersInfo()
                .setId(registerRequest.getUserId())
                .setSex(registerRequest.getSex())
                .setLabelFillFlag((byte) 1)
                .setLabelText(labelText)
                .setAgeStr(registerRequest.getAgeStr().replace("~", "-"));
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
        UsersResponse usersResponse = new UsersResponse(users, usersInfo);
        if (StringUtils.isEmpty(usersResponse.getHeadImg())) {
            usersResponse.setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
        }
        redisService.set(users.getToken(), JSONObject.toJSONString(usersResponse));
        redisService.expire(users.getToken(), TokenConstants.EXPIRE_SECONDS);
    }

    /**
     * 根据电话号码处理用户信息
     *
     * @param registerRequest
     * @return
     */
    private UsersResponse dealWithUser(RegisterRequest registerRequest) {
        // 登录日志记录
        LoginLog loginLog = new LoginLog();

        // 根据填入手机号查询是否存在该用户
        Users users = usersDao.queryUsersByTel(registerRequest.getTelephone());
        // 用户为空, 数据库添加用户基本信息
        if (users == null) {
            Users newUser = new Users()
                    .setTel(registerRequest.getTelephone())
                    .setStatus(UsersStatusEnums.active.getStatus())
                    // 随机账号生成和订单公共
                    .setAccount(OrderUtils.getRandomAccount())
                    .setToken(GetTokenUtil.getToken())
                    .setNickname(registerRequest.getTelephone())
                    .setSource(registerRequest.getSource());
            // 数据库插入用户基础信息
            usersMapper.insertSelective(newUser);
            Integer temporarySore = Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE_APP));
            BigDecimal money = new BigDecimal(sysConfigUtil.getSysConfig(SysConfigConstants.LOGIN_MONEY));
            if (StringUtils.isNotEmpty(registerRequest.getSource()) && ("android".equals(registerRequest.getSource().toLowerCase()) || "ios".equals(registerRequest.getSource().toLowerCase()))) {
                temporarySore = Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.SCORE_APP_REGISTER));
                money = BigDecimal.ZERO;
            }
            UsersInfo usersInfo = new UsersInfo()
                    .setId(newUser.getId())
                    .setChannel(registerRequest.getSource().equals("ios") || registerRequest.getSource().equals("weapp") ? registerRequest.getSource() : registerRequest.getChannel())
                    .setEmail("")
                    .setRegisterIp(registerRequest.getIp())
                    .setRegisterTime(new Date())
                    .setMoney(money)
                    .setTotalMoney(money)
                    .setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG))
                    .setSex(registerRequest.getSex())
                    .setScore(temporarySore)
                    .setTotalScore(temporarySore)
                    .setTemporarySore(temporarySore)
                    .setTemporarySoreTime(Date.from(LocalDateTime.now().plusDays(7).atZone(ZoneId.systemDefault()).toInstant()));
            // 数据库插入用户附属表信息
            usersInfoMapper.insertSelective(usersInfo);
            UsersResponse usersResponse = new UsersResponse(newUser, usersInfo);
            // 登录日志记录
            loginLog.setUserId(usersResponse.getId())
                    .setLoginTime(new Date())
                    .setPlatform(registerRequest.getPlatform())
                    .setIp(registerRequest.getIp())
                    .setVersion(registerRequest.getVersion())
                    .setPhoneModel(registerRequest.getPhoneModel());
            loginLogMapper.insertSelective(loginLog);

            // 根据用户手机号查看是否支付
            usersResponse.setIsPayOrder(this.isPayBytel(usersResponse.getTel()));
            redisService.set(newUser.getToken(), JSONObject.toJSONString(usersResponse));
            redisService.expire(newUser.getToken(), TokenConstants.EXPIRE_SECONDS);

            //注册埋点
            registSavePoint(registerRequest, usersInfo);

            return usersResponse;
        }

        // 存在用户
        Users existUser = usersDao.queryUsersByTel(registerRequest.getTelephone());
        if (null == existUser) {
            log.debug("===existUser is null===");
        }
        // 判断用户是否是h5匿名用户
        if (existUser.getStatus().byteValue() == UsersStatusEnums.unregister.getStatus()) {
            existUser.setStatus(UsersStatusEnums.active.getStatus());
        }
        UsersInfo existUsersInfo = usersInfoMapper.selectByPrimaryKey(existUser.getId());

        // 删除原来的redis
        // redisService.remove(existUser.getToken());
        // 数据库更新用户token信息
        existUser.setToken(GetTokenUtil.getToken());
        usersMapper.updateByPrimaryKeySelective(existUser);
        UsersResponse usersResponse = new UsersResponse(existUser, existUsersInfo);
        if (StringUtils.isEmpty(usersResponse.getHeadImg())) {
            usersResponse.setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
        }
        // 登录日志记录
        loginLog.setUserId(usersResponse.getId())
                .setLoginTime(new Date())
                .setPlatform(registerRequest.getPlatform())
                .setIp(registerRequest.getIp())
                .setVersion(registerRequest.getVersion())
                .setPhoneModel(registerRequest.getPhoneModel());
        loginLogMapper.insertSelective(loginLog);

        // 用户我的钱包明细判断有无登录赠送记录
        UsersBalanceRecordExample example = new UsersBalanceRecordExample();
        example.createCriteria()
                .andUserIdEqualTo(existUser.getId())
                .andSourceEqualTo("LOGIN_GIVE");
        List<UsersBalanceRecord> usersBalanceRecords = usersBalanceRecordMapper.selectByExample(example);
        if (usersBalanceRecords == null || usersBalanceRecords.size() <= 0) {

        }
        // 根据用户手机号查看是否支付
        usersResponse.setIsPayOrder(this.isPayBytel(usersResponse.getTel()));
        redisService.set(existUser.getToken(), JSONObject.toJSONString(usersResponse));
        redisService.expire(existUser.getToken(), TokenConstants.EXPIRE_SECONDS);
        return usersResponse;
    }

    private void registSavePoint(RegisterRequest registerRequest, UsersInfo usersInfo) {
        try {
            UserRegisterRequestDto requestDto = new UserRegisterRequestDto();
            BeanUtils.copyProperties(registerRequest, requestDto);
            //数据埋点字段对应
            requestDto.setChannel(TokenUtil.getChannel());
            requestDto.setPlatform(registerRequest.getSource());
            requestDto.setSource(registerRequest.getPlatform());
            requestDto.setUserId(usersInfo.getId());
            requestDto.setIp(registerRequest.getIp());
            requestDto.setUuid(TokenUtil.getUuid());
            requestDto.setImei(TokenUtil.getImei());
            requestDto.setOaid(TokenUtil.getOaid());
            requestDto.setOsVersion(String.valueOf(TokenUtil.getOsVersion()));
            mallClient.userRegister(requestDto);
        } catch (Exception e) {
            log.error("===注册埋点异常==={}", e);
        }
    }

    private void checkIsBlackTelList(String tel) {
        if (StringUtils.isNotEmpty(tel) && StringUtils.isNotEmpty(blackListTel)) {
            List<String> blackTelList = Arrays.asList(blackListTel.split(","));
            if (!CollectionUtils.isEmpty(blackTelList)) {
                if (blackTelList.contains(tel)) {
                    throw new ApiException("登录失败！");
                }
            }
        }
    }

    @Override
    public UsersResponse appLogin(LoginRequest loginRequest) {
        // 判断来源
        // 如果是小程序 ，取出openid 判断openid 是否存在，如果存在，取出第一条用户的登录成功
        if (StringUtil.isNotEmpty(loginRequest.getOpenid())) {
            List<Users> openUser = usersDao.queryUsersByOpenId(loginRequest.getOpenid());
            if (null == openUser || openUser.size() <= 0) {
                // 没有用户  去填写手机号
                throw new ApiException(ResultCode.NO_PHONE);
            } else {
                // 存在用户，取出第一个用户，登录成功
                Users users = openUser.get(0);
                // 校验手机号是否黑名单
                checkIsBlackTelList(users.getTel());
                users.setToken(GetTokenUtil.getToken());
                usersMapper.updateByPrimaryKeySelective(users);
                UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(users.getId());
                UsersResponse usersResponse = new UsersResponse(users, usersInfo);
                if (StringUtils.isEmpty(usersResponse.getHeadImg())) {
                    usersResponse.setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
                }
                usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
                // 该用户是否支付过
                Boolean isPayOrder = this.isPayBytel(users.getTel());
                usersResponse.setIsPayOrder(isPayOrder);
                // 登录日志记录
                LoginLog loginLog = new LoginLog();
                loginLog.setUserId(usersResponse.getId())
                        .setLoginTime(new Date())
                        .setPlatform(TokenUtil.getSource())
                        .setIp(loginRequest.getIp())
                        .setVersion(loginRequest.getVersion())
                        .setPhoneModel(loginRequest.getPhoneModel());
                loginLogMapper.insertSelective(loginLog);
                redisService.set(users.getToken(), JSONObject.toJSONString(usersResponse));
                redisService.expire(users.getToken(), TokenConstants.EXPIRE_SECONDS);
                updateAppLogin(usersResponse.getId(), usersResponse.getToken());
                return usersResponse;
            }

        }

        // 第一查看库有没有用户信息 app
        Users users = usersDao.queryUsersByUid(loginRequest.getUnionid());
        if (null == users) {
            throw new ApiException(ResultCode.NO_PHONE);
        }
        // uid 不等null
        // 判断手机号是否为空
        if (StringUtils.isEmpty(users.getTel())) {
            throw new ApiException(ResultCode.NO_PHONE);
        }
        // 校验手机号是否黑名单
        checkIsBlackTelList(users.getTel());
        // 判断用户来源是否是小程序 有没有记录openid
        if (StringUtil.isNotEmpty(loginRequest.getOpenid())) {
            if (null == users.getWxOpenid()) {
                users.setAppOpenid(loginRequest.getOpenid());
//                users.setWxOpenid(loginRequest.getOpenid());
            }
        }
        // 删除原来的redis
        // redisService.remove(users.getToken());
        users.setToken(GetTokenUtil.getToken());
        usersMapper.updateByPrimaryKeySelective(users);
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(users.getId());
        UsersResponse usersResponse = new UsersResponse(users, usersInfo);
        if (StringUtils.isEmpty(usersResponse.getHeadImg())) {
            usersResponse.setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
        }
        usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
        // 该用户是否支付过
        Boolean isPayOrder = this.isPayBytel(users.getTel());
        usersResponse.setIsPayOrder(isPayOrder);
        // 登录日志记录
        LoginLog loginLog = new LoginLog();
        loginLog.setUserId(usersResponse.getId())
                .setLoginTime(new Date())
                .setPlatform(loginRequest.getPlatform())
                .setIp(loginRequest.getIp())
                .setVersion(loginRequest.getVersion())
                .setPhoneModel(loginRequest.getPhoneModel());
        loginLogMapper.insertSelective(loginLog);
        redisService.set(users.getToken(), JSONObject.toJSONString(usersResponse));
        redisService.expire(users.getToken(), TokenConstants.EXPIRE_SECONDS);
        updateAppLogin(usersResponse.getId(), usersResponse.getToken());

        BigDecimal useSubsidyAmount_decimal = getUseSubsidyAmount(users.getId());
        usersResponse.setUseSubsidyAmount(useSubsidyAmount_decimal);
        usersResponse.setSubsidyAmountCount(new BigDecimal(4000));
        try {
            usersResponse.setTalentFlag(checkUserIsTalent(users.getId(), DynamicStatusEnums.PASS.getCode()));
            if (null == usersInfo.getIsQuality() || 0 == usersResponse.getIsQuality()) {
                if (1 == usersResponse.getTalentFlag()) {
                    usersResponse.setIsQuality(1);
                }else {
                    usersResponse.setIsQuality(checkUserIsTalent(users.getId(), null));
                }
            }
        } catch (Exception e) {
            log.error("===获取用户达人标志位异常==={}", users.getId());
            log.error("{}", e);
        }
        try {
            if (usersResponse.getIsQuality().equals(usersInfo.getIsQuality()) && usersResponse.getIsQuality().equals(1)) {
                usersInfo.setIsQuality(1);
                usersInfoMapper.updateByPrimaryKey(usersInfo);
            }
        } catch (Exception e) {
            log.error("===更新用户达人标志异常");
        }
        try {
            usersResponse.setPayFlag(0);
            DynamicDto dto = mallClient.queryCountByTelRpc(usersResponse.getTel());
            Integer payNum = dto.getNum();
            if (null != payNum && payNum > 0) {
                usersResponse.setPayFlag(1);
            }
        } catch (Exception e) {
            log.error("===获取用户支付订单总数异常==={}", e);
        }
        return usersResponse;
    }

    @Override
    public UsersResponse appLoginByIos(LoginRequest loginRequest) {
        // 判断来源
        // 如果是ios，取出openid 判断openid 是否存在，如果存在，取出第一条用户的登录成功
        if (StringUtil.isNotEmpty(loginRequest.getIosId())) {
            List<Users> openUser = usersDao.queryUsersByIosId(loginRequest.getIosId());
            if (null == openUser || openUser.size() <= 0) {
                String account = OrderUtils.getRandomAccount();
                Users newUser = new Users()
                        .setTel(null)
                        .setStatus(UsersStatusEnums.active.getStatus())
                        // 随机账号生成和订单公共
                        .setAccount(account)
                        .setToken(GetTokenUtil.getToken())
                        .setNickname(StringUtils.isEmpty(loginRequest.getPhone()) ? account : loginRequest.getPhone())
                        .setIosId(loginRequest.getIosId())
                        .setSource(loginRequest.getSource());
                // 数据库插入用户基础信息
                usersMapper.insertSelective(newUser);

                Integer temporarySore = Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE_APP));
                BigDecimal money = new BigDecimal(sysConfigUtil.getSysConfig(SysConfigConstants.LOGIN_MONEY));
                if (StringUtils.isNotEmpty(loginRequest.getSource()) && ("android".equals(loginRequest.getSource().toLowerCase()) || "ios".equals(loginRequest.getSource().toLowerCase()))) {
                    temporarySore = Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.SCORE_APP_REGISTER));
                    money = BigDecimal.ZERO;
                }
                UsersInfo usersInfo = new UsersInfo()
                        .setId(newUser.getId())
                        .setChannel(loginRequest.getSource().equals("ios") || loginRequest.getSource().equals("weapp") ? loginRequest.getSource() : loginRequest.getChannel())
                        .setEmail("")
                        .setRegisterIp(loginRequest.getIp())
                        .setRegisterTime(new Date())
                        .setMoney(money)
                        .setTotalMoney(money)
                        .setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG))
                        .setSex(loginRequest.getSex())
                        .setScore(0)
                        .setTemporarySore(temporarySore)
                        .setTemporarySoreTime(Date.from(LocalDateTime.now().plusDays(7).atZone(ZoneId.systemDefault()).toInstant()));
                // 数据库插入用户附属表信息
                usersInfoMapper.insertSelective(usersInfo);

                UsersResponse usersResponse = new UsersResponse(newUser, usersInfo);
                usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
                // 该用户是否支付过
                if (!StringUtils.isEmpty(newUser.getTel())) {
                    Boolean isPayOrder = this.isPayBytel(newUser.getTel());
                    usersResponse.setIsPayOrder(isPayOrder);
                    usersResponse.setIsBindTel(1);
                }else {
                    usersResponse.setIsBindTel(0);
                    usersResponse.setIsPayOrder(false);
                }
                try {
                    UserRegisterRequestDto requestDto = new UserRegisterRequestDto();
                    BeanUtils.copyProperties(loginRequest, requestDto);
                    //数据埋点字段对应
                    requestDto.setPlatform(loginRequest.getSource());
                    requestDto.setSource(loginRequest.getPlatform());
                    requestDto.setUserId(usersInfo.getId());
                    requestDto.setIp(loginRequest.getIp());
                    requestDto.setUuid(TokenUtil.getUuid());
                    requestDto.setImei(TokenUtil.getImei());
                    requestDto.setOaid(TokenUtil.getOaid());
                    requestDto.setOsVersion(String.valueOf(TokenUtil.getOsVersion()));
                    mallClient.userRegister(requestDto);
                } catch (Exception e) {
                    log.error("===注册埋点异常==={}", e);
                }
                redisService.set(newUser.getToken(), JSONObject.toJSONString(usersResponse));
                redisService.expire(newUser.getToken(), TokenConstants.EXPIRE_SECONDS);
                return usersResponse;
            } else {
                // 存在用户，取出第一个用户，登录成功
                Users users = openUser.get(0);
                users.setToken(GetTokenUtil.getToken());
                usersMapper.updateByPrimaryKeySelective(users);
                UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(users.getId());
                UsersResponse usersResponse = new UsersResponse(users, usersInfo);
                usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
                // 该用户是否支付过
                if (!StringUtils.isEmpty(users.getTel())) {
                    Boolean isPayOrder = this.isPayBytel(users.getTel());
                    usersResponse.setIsPayOrder(isPayOrder);
                    usersResponse.setIsBindTel(1);
                }else {
                    usersResponse.setIsBindTel(0);
                    usersResponse.setIsPayOrder(false);
                }
                // 登录日志记录
                LoginLog loginLog = new LoginLog();
                loginLog.setUserId(usersResponse.getId())
                        .setLoginTime(new Date())
                        .setPlatform(TokenUtil.getSource())
                        .setIp(loginRequest.getIp())
                        .setVersion(loginRequest.getVersion())
                        .setPhoneModel(loginRequest.getPhoneModel());
                loginLogMapper.insertSelective(loginLog);
                redisService.set(users.getToken(), JSONObject.toJSONString(usersResponse));
                redisService.expire(users.getToken(), TokenConstants.EXPIRE_SECONDS);
                updateAppLogin(usersResponse.getId(), usersResponse.getToken());
                return usersResponse;
            }

        }

        // 第一查看库有没有用户信息 app
        Users users = usersDao.queryUsersByUid(loginRequest.getUnionid());
        if (null == users) {
            throw new ApiException(ResultCode.NO_PHONE);
        }
        // uid 不等null
        // 判断手机号是否为空
        if (StringUtils.isEmpty(users.getTel())) {
            throw new ApiException(ResultCode.NO_PHONE);
        }
        // 判断用户来源是否是小程序 有没有记录openid
        if (StringUtil.isNotEmpty(loginRequest.getOpenid())) {
            if (null == users.getWxOpenid()) {
                users.setWxOpenid(loginRequest.getOpenid());
            }
        }
        users.setToken(GetTokenUtil.getToken());
        usersMapper.updateByPrimaryKeySelective(users);
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(users.getId());
        UsersResponse usersResponse = new UsersResponse(users, usersInfo);
        if (StringUtils.isEmpty(usersResponse.getHeadImg())) {
            usersResponse.setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
        }
        usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
        // 该用户是否支付过
        if (!StringUtils.isEmpty(users.getTel())) {
            Boolean isPayOrder = this.isPayBytel(users.getTel());
            usersResponse.setIsPayOrder(isPayOrder);
            usersResponse.setIsBindTel(1);
        }else {
            usersResponse.setIsBindTel(0);
            usersResponse.setIsPayOrder(false);
        }
        // 登录日志记录
        LoginLog loginLog = new LoginLog();
        loginLog.setUserId(usersResponse.getId())
                .setLoginTime(new Date())
                .setPlatform(loginRequest.getPlatform())
                .setIp(loginRequest.getIp())
                .setVersion(loginRequest.getVersion())
                .setPhoneModel(loginRequest.getPhoneModel());
        loginLogMapper.insertSelective(loginLog);
        redisService.set(users.getToken(), JSONObject.toJSONString(usersResponse));
        redisService.expire(users.getToken(), TokenConstants.EXPIRE_SECONDS);
        updateAppLogin(usersResponse.getId(), usersResponse.getToken());

        BigDecimal useSubsidyAmount_decimal = getUseSubsidyAmount(users.getId());
        usersResponse.setUseSubsidyAmount(useSubsidyAmount_decimal);
        usersResponse.setSubsidyAmountCount(new BigDecimal(4000));

        try {
            usersResponse.setTalentFlag(checkUserIsTalent(users.getId(), DynamicStatusEnums.PASS.getCode()));
            if (null == usersInfo.getIsQuality() || 0 == usersResponse.getIsQuality()) {
                if (1 == usersResponse.getTalentFlag()) {
                    usersResponse.setIsQuality(1);
                }else {
                    usersResponse.setIsQuality(checkUserIsTalent(users.getId(), null));
                }
            }
        } catch (Exception e) {
            log.error("===获取用户达人标志位异常==={}", users.getId());
            log.error("{}", e);
        }
        try {
            if (usersResponse.getIsQuality().equals(usersInfo.getIsQuality()) && usersResponse.getIsQuality().equals(1)) {
                usersInfo.setIsQuality(1);
                usersInfoMapper.updateByPrimaryKey(usersInfo);
            }
        } catch (Exception e) {
            log.error("===更新用户达人标志异常");
        }
        try {
            usersResponse.setPayFlag(0);
            DynamicDto dto = mallClient.queryCountByTelRpc(usersResponse.getTel());
            Integer payNum = dto.getNum();
            if (null != payNum && payNum > 0) {
                usersResponse.setPayFlag(1);
            }
        } catch (Exception e) {
            log.error("===获取用户支付订单总数异常==={}", e);
        }
        return usersResponse;
    }

    /**
     * 获取用户 补贴消费金信息
     * @param userId
     * @return
     */
    @Override
    public BigDecimal getUseSubsidyAmount(Integer userId) {
        BigDecimal useSubsidyAmount_decimal = BigDecimal.ZERO;
        try {
            String useSubsidyAmount = redisService.get(RedisConstants.RECORD_SUBSIDYKEY_USE_APP + userId);
            log.info("===useSubsidyAmount==={}", useSubsidyAmount);
            useSubsidyAmount_decimal = BigDecimal.valueOf(Double.valueOf(null == useSubsidyAmount ? "0" : useSubsidyAmount));
            if (useSubsidyAmount_decimal.compareTo(new BigDecimal("4000")) > 0) {
                useSubsidyAmount_decimal = new BigDecimal("4000");
            }
        } catch (Exception e) {
            log.error("===e==={}", e);
            useSubsidyAmount_decimal = BigDecimal.ZERO;
        }
        return useSubsidyAmount_decimal;
    }

    @Override
    public UsersResponse wxLogin(LoginRequest loginRequest) {
        if (StringUtil.isNotEmpty(loginRequest.getOpenid())) {
            if (TokenUtil.getChannel().contains("xfh-pyq")) {
                String aid = TokenUtil.getRequest().getHeader("aid");
                new Thread(() -> {
                    AddUserActions addUserActions = new AddUserActions();
                    addUserActions.init(loginRequest.getOpenid(), 1111385575L, ActionType.ACTIVATE_APP, aid);
                    try {
                        UserActionsAddResponse response = addUserActions.addUserActions();
                        log.debug("上报结果：{}", response.toString());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }).start();
            }
            List<Users> openUser = usersDao.queryUsersByOpenId(loginRequest.getOpenid());
            if (null == openUser || openUser.size() <= 0) {
                // 没有用户，直接触发登录
                String token = GetTokenUtil.getToken();
                loginRequest.setUnionid(null);
                UsersResponse usersResponse = this.toRegister(loginRequest, token,"wx");
                usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
                usersResponse.setIsPayOrder(false);
                redisService.set(token, JSONObject.toJSONString(usersResponse));
                redisService.expire(token, TokenConstants.EXPIRE_SECONDS);
                LoginLog loginLog = new LoginLog();
                loginLog.setUserId(usersResponse.getId())
                        .setLoginTime(new Date())
                        .setPlatform(TokenUtil.getSource())
                        .setIp(loginRequest.getIp())
                        .setVersion(loginRequest.getVersion())
                        .setPhoneModel(loginRequest.getPhoneModel());
                loginLogMapper.insertSelective(loginLog);
                return usersResponse;
            } else {
                // 存在用户，取出第一个用户，登录成功
                Users users = openUser.get(0);
                users.setToken(GetTokenUtil.getToken());
                usersMapper.updateByPrimaryKeySelective(users);
                UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(users.getId());
                UsersResponse usersResponse = new UsersResponse(users, usersInfo);
                if (StringUtils.isEmpty(usersResponse.getHeadImg())) {
                    usersResponse.setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
                }
                usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
                usersResponse.setIsPayOrder(false);
                // 登录日志记录
                LoginLog loginLog = new LoginLog();
                loginLog.setUserId(usersResponse.getId())
                        .setLoginTime(new Date())
                        .setPlatform(loginRequest.getPlatform())
                        .setIp(loginRequest.getIp())
                        .setVersion(loginRequest.getVersion())
                        .setPhoneModel(loginRequest.getPhoneModel());
                loginLogMapper.insertSelective(loginLog);
                redisService.set(users.getToken(), JSONObject.toJSONString(usersResponse));
                redisService.expire(users.getToken(), TokenConstants.EXPIRE_SECONDS);
                return usersResponse;
            }

        } else {
            throw new ApiException("openid获取失败");
        }
    }

    /**
     * 是否支付过订单
     */
    private Boolean isPayBytel(String tel) {
        DynamicDto dto = mallClient.queryCountByTelRpc(tel);
        Integer payNum = dto.getNum();
        if (payNum > 0) {
            return true;
        }
        return false;
    }

    @Override
    public UsersResponse appRegister(LoginRequest loginRequest) {
        log.info("注册：requet : {}", JSONObject.toJSONString(loginRequest));
        // 校验验证码是否存在
        String smsCode = redisService.get(SmsConstant.REDIS_KEY_PREFIX_AUTH_CODE_LOGINPHONE + loginRequest.getPhone());
        if (StringUtils.isEmpty(smsCode) || !loginRequest.getSmsCode().equals(smsCode)) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.VERIFICATION_CODE_ERROR));
        }
        // 校验手机号是否存在
        Users users = usersDao.queryUsersByTel(loginRequest.getPhone());
        log.info("用户信息：{}", JSONObject.toJSONString(users));

        // 如果手机号已存在 判断有没有存在uid 如果不存在uid 直接保存uid 和 openid 并且登录成功
        if (null != users) {
            if (StringUtils.isNotEmpty(users.getWxUnionid())) {
                throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.MOBILE_ACCOUNT_ALREADY_EXISTS));
            } else {
                String token = GetTokenUtil.getToken();
                UsersResponse usersResponse = this.updateUsersInfo(loginRequest, users, token);
                usersResponse.setIsPayOrder(this.isPayBytel(usersResponse.getTel()));
                redisService.set(token, JSONObject.toJSONString(usersResponse));
                redisService.expire(token, TokenConstants.EXPIRE_SECONDS);
                updateAppLogin(usersResponse.getId(), usersResponse.getToken());
                return usersResponse;
            }
        } else {
            // 如果手机号不存在 判断uid 是否为空
            if (StringUtils.isNotEmpty(loginRequest.getUnionid())) {
                // 如果uid 不为空 判断uid 用户是否存在
                Users uid = usersDao.queryUsersByUid(loginRequest.getUnionid());
                // 如果uid 用户存在判断手机号是否为空，
                if (null == uid) {
                    // 如果不存在 保存uid 和openid 和 手机号 并且登录成功
                    String token = GetTokenUtil.getToken();
                    UsersResponse usersResponse = this.toRegister(loginRequest, token,"app");
                    usersResponse.setIsPayOrder(this.isPayBytel(usersResponse.getTel()));
                    redisService.set(token, JSONObject.toJSONString(usersResponse));
                    redisService.expire(token, TokenConstants.EXPIRE_SECONDS);
                    updateAppLogin(usersResponse.getId(), usersResponse.getToken());
                    return usersResponse;
                } else {
                    // 不为空更新手机号和openid 并且登录成功
                    String token = GetTokenUtil.getToken();
                    UsersResponse usersResponse = this.updateUsersInfo(loginRequest, uid, token);
                    usersResponse.setIsPayOrder(this.isPayBytel(usersResponse.getTel()));
                    redisService.set(token, JSONObject.toJSONString(usersResponse));
                    redisService.expire(token, TokenConstants.EXPIRE_SECONDS);
                    updateAppLogin(usersResponse.getId(), usersResponse.getToken());
                    return usersResponse;
                }
            } else {
                // 如果uid 为空 保存手机号和openid 并且登录成功
                String token = GetTokenUtil.getToken();
                UsersResponse usersResponse = this.toRegister(loginRequest, token,"app");
                usersResponse.setIsPayOrder(this.isPayBytel(usersResponse.getTel()));
                redisService.set(token, JSONObject.toJSONString(usersResponse));
                redisService.expire(token, TokenConstants.EXPIRE_SECONDS);
                updateAppLogin(usersResponse.getId(), usersResponse.getToken());
                return usersResponse;
            }
        }
    }

    /**
     * h5注册登录
     * @param loginRequest
     * @return
     */
    @Override
    public UsersResponse h5Register(LoginRequest loginRequest) {
        log.info("h5注册：requet : {}", JSONObject.toJSONString(loginRequest));
        // 校验验证码是否存在
        String smsCode = redisService.get(SmsConstant.REDIS_KEY_PREFIX_AUTH_CODE_LOGINPHONE + loginRequest.getPhone());
        if (StringUtils.isNotEmpty(loginRequest.getSmsCode())) {
            if (StringUtils.isEmpty(smsCode) || !smsCode.equals(loginRequest.getSmsCode())) {
                throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.VERIFICATION_CODE_ERROR));
            }
        }else {
            String serialNumber = loginRequest.getSerialNumber();
            if (StringUtils.isEmpty(serialNumber)) {
                log.error("=== h5 register is fail, because smsCode and serialNum is null! ===");
                log.error("===smsCode:{}, serialNumber:{}", smsCode, serialNumber);
                throw new ApiException("登录有误，请切换成验证码登录！");
            }
            String phone = SmsToolsUtil.resolutionSmsToolsPhone(serialNumber);
            if (!phone.equals(loginRequest.getPhone())) {
                log.error("=== h5 register is fail, because phone not equal to serialNumber! ===");
                log.error("=== phone:{}, serialNumber:{}, serialPhone:{}", loginRequest.getPhone(), serialNumber, phone);
                throw new ApiException("登录有误，请切换成验证码登录！");
            }
        }

        // 校验手机号是否存在
        Users users = usersDao.queryUsersByTel(loginRequest.getPhone());
        log.info("用户信息：{}", JSONObject.toJSONString(users));

        // 如果手机号已存在 判断有没有存在uid 如果不存在uid 直接保存uid 和 openid 并且登录成功
        if (null != users) {
            String token = GetTokenUtil.getToken();
            UsersResponse usersResponse = this.updateUsersInfo(loginRequest, users, token);
            usersResponse.setIsPayOrder(this.isPayBytel(usersResponse.getTel()));
            redisService.set(token, JSONObject.toJSONString(usersResponse));
            redisService.expire(token, TokenConstants.EXPIRE_SECONDS);
//                updateAppLogin(usersResponse.getId(), usersResponse.getToken());
            return usersResponse;
        } else {
            // 如果uid 为空 保存手机号和openid 并且登录成功
            String token = GetTokenUtil.getToken();
            UsersResponse usersResponse = this.toRegister(loginRequest, token,"h5");
            usersResponse.setIsPayOrder(this.isPayBytel(usersResponse.getTel()));
            redisService.set(token, JSONObject.toJSONString(usersResponse));
            redisService.expire(token, TokenConstants.EXPIRE_SECONDS);
//                updateAppLogin(usersResponse.getId(), usersResponse.getToken());
            return usersResponse;
        }
    }

    @Transactional
    @Override
    public UsersResponse updateUsersInfo(LoginRequest loginRequest, Users users, String token) {
        users.setStatus(UsersStatusEnums.active.getStatus())
                .setAppOpenid(loginRequest.getOpenid())
                .setToken(token)
                .setAccount(OrderUtils.getRandomAccount())
                .setTel(loginRequest.getPhone())
                .setNickname(loginRequest.getNickname())
                .setWxUnionid(loginRequest.getUnionid());

        usersMapper.updateByPrimaryKeySelective(users);
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(users.getId());
        usersInfo.setHeadImg(loginRequest.getHeadimgurl());
        if (StringUtils.isEmpty(usersInfo.getHeadImg())) {
            usersInfo.setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
        }
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
        return new UsersResponse(users, usersInfo);
    }


    @Transactional
    @Override
    public UsersResponse toRegister(LoginRequest loginRequest, String token,String from) {
        Users users = new Users()
                .setAccount(OrderUtils.getRandomAccount())
                .setNickname(Optional.ofNullable(loginRequest.getNickname()).orElse("会员" + OrderUtils.getRandomAccount()))
                .setTel(loginRequest.getPhone())
                .setSource(TokenUtil.getSource())
                .setPwd("xxx")
                .setToken(token)
                .setWxUnionid(loginRequest.getUnionid())
                .setStatus(UsersStatusEnums.active.getStatus());
        // 判断用户来源是否是小程序 有没有记录openid
        if ("wx".equals(from)){
            users.setWxOpenid(loginRequest.getOpenid());
        }
        if ("app".equals(from)){
            users.setAppOpenid(loginRequest.getOpenid());
        }
        usersMapper.insertSelective(users);

        Integer defaultScore = Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE_APP));
        UsersInfo usersInfo = new UsersInfo()
                .setId(users.getId())
                .setChannel(TokenUtil.getChannel())
                .setEmail("")
                .setRegisterIp(loginRequest.getIp())
                .setRegisterTime(new Date())
                .setSex(Optional.ofNullable(loginRequest.getSex()).orElse(0))
                .setHeadImg(Optional.ofNullable(loginRequest.getHeadimgurl()).orElse(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG)))
                .setMoney(new BigDecimal(sysConfigUtil.getSysConfig(SysConfigConstants.LOGIN_MONEY)))
                .setTotalMoney(new BigDecimal(sysConfigUtil.getSysConfig(SysConfigConstants.LOGIN_MONEY)))
                .setScore(defaultScore)
                .setTaskScore(0)
                .setTemporarySore(defaultScore)
                .setTotalScore(defaultScore)
                .setTemporarySoreTime(Date.from(LocalDateTime.now().plusDays(7).atZone(ZoneId.systemDefault()).toInstant()));
        usersInfoMapper.insertSelective(usersInfo);
        usersInfo = usersInfoMapper.selectByPrimaryKey(users.getId());

        try {
            //注册埋点
            RegisterRequest registerRequest = new RegisterRequest();
            BeanUtils.copyProperties(loginRequest, usersInfo);
            registSavePoint(registerRequest, usersInfo);
        } catch (Exception e) {
            log.error("===异常==={}", e);
        }

        return new UsersResponse(users, usersInfo);
    }

    private Integer getInitScore(String sourcePlatform) {
        try {
            if (StringUtils.isNotBlank(sourcePlatform)) {
                String platform = sourcePlatform.toUpperCase() + "_SCORE";
                String val = sysConfigUtil.getSysConfig(platform);
                if (!StringUtils.isBlank(val)) {
                    return Integer.parseInt(val);
                } else {
                    return Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE_APP));
                }
            } else {
                return Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE_APP));
            }
        } catch (Exception e) {
            return Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE_APP));
        }

    }


    @Override
    public JSONObject getToken(HttpServletRequest request) throws IOException {
        // APP-微信登录
        String code = request.getParameter("code");
        String url = null;
        url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
                // + "appid=" + APPID
                // + "&secret=" + SECRET
                + "&code=" + code
                + "&grant_type=authorization_code";
        JSONObject wechatAccessToken = AuthUtil.getAuthJson(url);
        return wechatAccessToken;
    }


    @Override
    public CommonResult bindNewPhone(RegisterRequest registerRequest) {
        //首先比对验证码是否失效
        String redisAuthCode = redisService.get(SmsConstant.REDIS_KEY_PREFIX_AUTH_CODE_BINDPHOEN + registerRequest.getTelephone());
        if (StringUtils.isEmpty(redisAuthCode)) {
            //如果未取到则过期
            return CommonResult.failed(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.VERIFICATION_OUT));
        }
        if (!"".equals(redisAuthCode) && !registerRequest.getAuthCode().equals(redisAuthCode)) {
            return CommonResult.failed(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.VERIFICATION_CODE_ERROR));
        }
        Users users = usersDao.queryUsersByTel(registerRequest.getTelephone());
        if (null != users) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.PHONE_REGISTERED));
        }
        // 更新用户手机号
        usersDao.updatePhoneByUserId(registerRequest.getUserId(), registerRequest.getTelephone());
        Users baseUserInfo = usersMapper.selectByPrimaryKey(registerRequest.getUserId());
        UsersInfo extraUserInfo = usersInfoMapper.selectByPrimaryKey(registerRequest.getUserId());
        UsersResponse usersResponse = new UsersResponse(baseUserInfo, extraUserInfo);
        if (StringUtils.isEmpty(usersResponse.getHeadImg())) {
            usersResponse.setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
        }
        redisService.set(registerRequest.getToken(), JSONObject.toJSONString(usersResponse));
        redisService.expire(registerRequest.getToken(), TokenConstants.EXPIRE_SECONDS);
        return CommonResult.success(usersResponse);
    }

    @Override
    public CommonResult checkPhoneExist(RegisterRequest registerRequest) {
        //首先比对验证码是否失效
        String redisAuthCode = redisService.get(SmsConstant.REDIS_KEY_PREFIX_AUTH_CODE_BINDPHOEN + registerRequest.getTelephone());
        if (StringUtils.isEmpty(redisAuthCode)) {
            //如果未取到则过期
            return CommonResult.failed(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.VERIFICATION_OUT));
        }
        if (!"".equals(redisAuthCode) && !registerRequest.getAuthCode().equals(redisAuthCode)) {
            return CommonResult.failed(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.VERIFICATION_CODE_ERROR));
        }
        UsersExample usersExample = new UsersExample();
        usersExample.createCriteria()
                .andIdEqualTo(registerRequest.getUserId())
                .andTelEqualTo(registerRequest.getTelephone());
        List<Users> users = usersMapper.selectByExample(usersExample);
        if (users.size() > 0) {
            return CommonResult.success(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ALLOW_CONTINUE_OPERATION));
        }
        return CommonResult.failed(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.NUMBER_NOT_EXIST));
    }

    @Override
    public UsersResponse iosLogin(String account) {
        UsersExample example = new UsersExample();
        example.createCriteria()
                .andAccountEqualTo(account);
        Users users = usersMapper.selectByExample(example).get(0);
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(users.getId());
        UsersResponse usersResponse = new UsersResponse(users, usersInfo);
        if (StringUtils.isEmpty(usersResponse.getHeadImg())) {
            usersResponse.setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
        }
        String token = GetTokenUtil.getToken();
        usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
        redisService.set(token, JSONObject.toJSONString(usersResponse));
        redisService.expire(token, TokenConstants.EXPIRE_SECONDS);
        return usersResponse;
    }

    @Override
    public UsersResponse h5Login(String source, String channel, String sourcePlatform, String token) {
        UsersResponse usersResponse = new UsersResponse();
        usersResponse.setChannel(channel);
        usersResponse.setSource(source);
        String account = AccountUtil.getRandomAccount();
        usersResponse.setAccount(account);
        usersResponse.setNickname("用户" + account);
        if (StringUtils.isEmpty(token)) {
            token = GetTokenUtil.getToken();
        }
        usersResponse.setToken(token);
        usersResponse.setStatus(UsersStatusEnums.unregister.getStatus());
        usersResponse.setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
        if (!StringUtils.isBlank(sourcePlatform)) {
            String platform = sourcePlatform.toUpperCase() + "_SCORE";
            if (sourcePlatform.equals("ssvip")) {
                platform = sourcePlatform.toUpperCase() + "_NEW_SCORE";
            }
//            String platform = sourcePlatform.toUpperCase() + "_SCORE";
            log.info("h5Login的登录信息platform:{}",platform);
            String val = sysConfigUtil.getSysConfig(platform);
            log.info("h5login 缓存中的积分：{} ",val);
            if (!StringUtils.isBlank(val)) {
                usersResponse.setScore(Integer.valueOf(val));
                usersResponse.setTotalScore(Integer.valueOf(val));
            } else {
                usersResponse.setScore(Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE)));
                usersResponse.setTotalScore(Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE)));
            }

        } else {
            usersResponse.setScore(Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE)));
            usersResponse.setTotalScore(Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE)));
        }
        log.info("h5Login登录的用户积分:{}",usersResponse.getScore());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if ("x".equals(sourcePlatform)
                || "x2".equals(sourcePlatform)
                || "svip".equals(sourcePlatform)
                || "vip".equals(sourcePlatform)) {
            // 短信的渠道最后一天过期
            Calendar ca = Calendar.getInstance();
            ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
            try {
                Date date = sdf.parse(DateFormatUtils.format(ca.getTime(), "yyyy-MM-dd 23:59:59"));
                usersResponse.setBeforeDawnTime(date.getTime());
            } catch (Exception e) {
                e.printStackTrace();
            }
            usersResponse.setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
        } else {
            // 其他渠道当天过期
            try {
                Date date = sdf.parse(DateFormatUtils.format(new Date(), "yyyy-MM-dd 23:59:59"));
                usersResponse.setBeforeDawnTime(date.getTime());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        usersResponse.setMoney(new BigDecimal(sysConfigUtil.getSysConfig(SysConfigConstants.LOGIN_MONEY)));
        usersResponse.setLockMoney(new BigDecimal(0));
        usersResponse.setTotalMoney(new BigDecimal(0));
        usersResponse.setBrokerageNum(new BigDecimal(0));
        usersResponse.setFollow(0);
        usersResponse.setFans(0);
        usersResponse.setIsVip((byte) 0);
        usersResponse.setPraise(0);
        usersResponse.setDynamicSum(0);
        usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
        usersResponse.setVipMoney(0);
        usersResponse.setIsOpenLive((byte) 0);
        usersResponse.setIsZombie((byte) 0);
        usersResponse.setRegisterTime(new Date());
        redisService.set(token, JSONObject.toJSONString(usersResponse));
        if ("x".equals(sourcePlatform)
                || "x2".equals(sourcePlatform)
                || "svip".equals(sourcePlatform)
                || "vip".equals(sourcePlatform)) {
            redisService.expire(token, TokenConstants.EXPIRE_SECONDS);
        } else {
            redisService.expire(token, TokenConstants.EXPIRE_SECONDS_V2);
        }
        return usersResponse;
    }

    @Override
    public void saveOpenId(Integer userId, String openid) {
        Users users = usersMapper.selectByPrimaryKey(userId);
        if (null != users) {
            users.setWxOpenid(openid);
            usersMapper.updateByPrimaryKeySelective(users);
        }
    }

    @Resource
    private UsersAppLoginDao usersAppLoginDao;


    @Override
    public void saveAppLogin(AppLoginRequest request) {
        String channel = TokenUtil.getCha();
        request.setChannel(channel);

        if (request.getPlatform().equals("ios")) {
            usersAppLoginDao.saveAndUpdate(request);
            return;
        }

        if (!check(request.getOsVersion(), request.getImei(), request.getOaid())) return;

        if (StringUtils.isNotEmpty(request.getImei())) {
            boolean contains = request.getImei().contains(",");
            if (contains) {
                String[] split = request.getImei().split(",");
                request.setImei(split[0]);
                request.setImeiVice(split[1]);
            }
        }

        if (!usersAppLoginDao.existById(request.getOsVersion(), request.getOsVersion() < 10 ? request.getImei() : request.getOaid())) {
            usersAppLoginDao.saveAndUpdate(request);
        }

        if (StringUtils.isEmpty(channel) || !request.getPlatform().equals("android")) {
            return;
        }
    }

    @Override
    public CommonResult<UsersResponse> wxUnionIdLogin(RegisterRequest registerRequest) {
        UsersResponse usersResponse = new UsersResponse();
        LoginLog loginLog = new LoginLog();
        Users uidUsers = usersDao.queryUsersByUid(registerRequest.getUnionid());
        if (StringUtils.isNotBlank(registerRequest.getUnionid()) && null != uidUsers) {
            log.info("===wxUnionIdLogin user not null===WxOpenid{}", registerRequest.getOpenid());
            uidUsers.setWxOpenid(registerRequest.getOpenid());
            usersMapper.updateByPrimaryKeySelective(uidUsers);
            UsersInfo existUsersInfo = usersInfoMapper.selectByPrimaryKey(uidUsers.getId());
            usersResponse = new UsersResponse(uidUsers, existUsersInfo);
            usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
            // 登录日志记录
            loginLog.setUserId(usersResponse.getId())
                    .setLoginTime(new Date())
                    .setPlatform(registerRequest.getPlatform())
                    .setIp(registerRequest.getIp())
                    .setVersion(registerRequest.getVersion())
                    .setPhoneModel(registerRequest.getPhoneModel());
            loginLogMapper.insertSelective(loginLog);
            loginLog.setUserId(usersResponse.getId())
                    .setLoginTime(new Date())
                    .setPlatform(registerRequest.getPlatform())
                    .setIp(registerRequest.getIp())
                    .setVersion(registerRequest.getVersion())
                    .setPhoneModel(registerRequest.getPhoneModel());
            loginLogMapper.insertSelective(loginLog);


            // 该用户是否支付过
            usersResponse.setIsPayOrder(this.isPayBytel(usersResponse.getTel()));
            String cacheUserTokenKey = uidUsers.getToken();
            redisService.set(cacheUserTokenKey, JSONObject.toJSONString(usersResponse),TokenConstants.EXPIRE_SECONDS);
        } else {
            List<Users> users = usersDao.queryUsersByOpenId(registerRequest.getOpenid());
            if (!CollectionUtils.isEmpty(users)) {
                Users openIdUser = users.get(0);
                UsersInfo existUsersInfo = usersInfoMapper.selectByPrimaryKey(openIdUser.getId());
                usersResponse = new UsersResponse(openIdUser, existUsersInfo);
                usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
                // 登录日志记录
                loginLog.setUserId(usersResponse.getId())
                        .setLoginTime(new Date())
                        .setPlatform(registerRequest.getPlatform())
                        .setIp(registerRequest.getIp())
                        .setVersion(registerRequest.getVersion())
                        .setPhoneModel(registerRequest.getPhoneModel());
                loginLogMapper.insertSelective(loginLog);
                // 该用户是否支付过
//                usersResponse.setIsPayOrder(this.isPayBytel(usersResponse.getTel()));
                String cacheUserTokenKey = openIdUser.getToken();
                redisService.set(cacheUserTokenKey, JSONObject.toJSONString(usersResponse),TokenConstants.EXPIRE_SECONDS);

            } else {
                //注册一个新用户
                String token = GetTokenUtil.getToken();
                LoginRequest loginRequest = new LoginRequest();
                loginRequest.setUnionid(registerRequest.getUnionid());
                loginRequest.setOpenid(registerRequest.getOpenid());
                loginRequest.setPhoneModel(registerRequest.getPhoneModel());
                loginRequest.setIp(registerRequest.getIp());
                loginRequest.setPlatform(registerRequest.getPlatform());
                loginRequest.setVersion(registerRequest.getVersion());
                usersResponse = this.toRegister(loginRequest, token, "wx");
                usersResponse.setActivityMax(new BigDecimal(680));// 默认给用户680元的红包
                usersResponse.setIsPayOrder(false);
                String cacheUserTokenKey =  token;
                redisService.set(cacheUserTokenKey, JSONObject.toJSONString(usersResponse),TokenConstants.EXPIRE_SECONDS);

                loginLog.setUserId(usersResponse.getId())
                        .setLoginTime(new Date())
                        .setPlatform(TokenUtil.getSource())
                        .setIp(loginRequest.getIp())
                        .setVersion(loginRequest.getVersion())
                        .setPhoneModel(loginRequest.getPhoneModel());
                loginLogMapper.insertSelective(loginLog);
            }
        }
        return CommonResult.success(usersResponse);
    }

    public void updateAppLogin(Integer userId, String token) {
        String imei = TokenUtil.getImei();
        String oaid = TokenUtil.getOaid();
        String platform = TokenUtil.getPlatform();
        Integer osVersion = TokenUtil.getOsVersion();
        String channel = TokenUtil.getCha();

        if (platform.equals("ios") || !check(osVersion, imei, oaid)) return;

        if (StringUtils.isNotEmpty(imei)) {
            boolean contains = imei.contains(",");
            if (contains) {
                String[] split = imei.split(",");
                imei = split[0];
            }
        }
        usersAppLoginDao.updateUserId(osVersion, osVersion < 10 ? imei : oaid, userId);
        if (StringUtils.isEmpty(channel)) {
            return;
        }
    }

    private void advertReport(String channel, Integer osVersion, String imei, String oaid, String type) {

        boolean ks = channel.contains("ytjj-ks");
        //快手，头条，抖音渠道
        if (ks || channel.contains("ytjj-tt") || channel.contains("ytjj-dy")) {
            try {
                String advertPlatform = ks ? "KS" : "TT";

                String imeiMD5 = osVersion < 10 ? MD5Util.MD5(imei) : imei;

                if (null == osVersion) {
                    log.warn("osVersion is null");
                    return;
                }
                //获取推广回调
                AdvertCallbackDto advertCallback = usersAppLoginDao.findAdvertCallbackByid(osVersion, advertPlatform, osVersion < 10 ? imeiMD5 : oaid,type);

                if (null != advertCallback) {
                    //检查是否已经上报
                    if (usersAppLoginDao.existByIdPlaType(osVersion, osVersion < 10 ? imeiMD5 : oaid, advertPlatform, type)) {
                        return;
                    }
                    advertCallback.setType(type);
                    advertCallback.setAdvertPlatform(advertPlatform);
                    advertCallback.setChannel(channel);
                    advertCallback.setImei(imeiMD5);
                    advertCallback.setPlatform(TokenUtil.getPlatform());
                    advertCallback.setOaid(oaid);
                    usersAppLoginDao.saveAdvertReport(advertCallback);
                }
            } catch (Exception e) {
                e.printStackTrace();

            }
        }
    }

    private boolean check(Integer osVersion, String imei, String oaid) {
        if (osVersion == null) return false;
        if (osVersion < 10 && StringUtils.isNotEmpty(imei)) return true;
        if (osVersion >= 10 && StringUtils.isNotEmpty(oaid)) return true;
        return false;
    }


}
